home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / netstsr / spoold.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  21.7 KB  |  858 lines

  1. /************************************************************************/
  2. /*                                                                      */
  3. /*    spoold.c                                                            */
  4. /*                                                                      */
  5. /*    Durch bloßes Ändern der Extension im Dateinamen, läßt sich Pro-   */
  6. /*    gramm als normale GEM-Anwendung oder aber als Accessory betrei-   */
  7. /*    ben.                                                              */
  8. /*    Das Programm zeigt in einem Fenster die aktuellen Neuigkeiten an. */
  9. /*                                                                      */
  10. /*    Copyright (c)  FORTEC/pm 1989                                     */
  11. /*                                                                      */
  12. /************************************************************************/
  13.  
  14. /* -------------------------------------------------------------------- */
  15. /*    Headerdateien einbinden.                                          */
  16. /* -------------------------------------------------------------------- */
  17.  
  18. #include <aes.h>
  19. #include <stdio.h>
  20. #include <tos.h>
  21. #include <vdi.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #include <time.h>
  26. #include "tcpdef.h"
  27.  
  28. #define LINESIZE 70L
  29. #define NUMLINES 8
  30.  
  31. #define WINW     500
  32. #define WINH     200
  33. #define ZH 6
  34. #define INBUFSIZE 4096
  35. #define TRUE 1
  36. #define FALSE 0
  37. #define mmin(a,b) (((a) < (b)) ? (a) : (b))
  38.  
  39. #define FILE_BUF_SIZE      4096
  40. #define noDEBUG
  41.  
  42. DESTI desti;
  43. TCPSTAT tstat;
  44.  
  45. char *myid = "@(#)ANS-SPD 1.0 pm/hw";
  46.  
  47. #define SYSBASE ((SYSHDR*)0x4f2L)
  48.  
  49. static BASPAG **oldpd;
  50. long set_pd(void);
  51. long restore_pd(void);
  52.  
  53. char *term;
  54. int tcp_buff = 2048;
  55. char data[INBUFSIZE];
  56.  
  57. long number,timev;
  58. int tcp_ok;
  59. char o_str[100];
  60. char file_buffer[FILE_BUF_SIZE];
  61. char filename[50];
  62. char printer[50];
  63. char printhost[50];
  64. char hostname[50];
  65. char user[30];
  66. int  o_len;
  67. long lendata;
  68. long lensent;
  69. char *term;
  70. int tcp;
  71. char response;
  72. long filelength;
  73. char * file_to_print;
  74. FILE * fin;
  75. int x, y,
  76. kstate,
  77. key,
  78. clicks,
  79. event,
  80. state;
  81. int pipe[8];
  82. int quit;
  83.  
  84. char log_text[NUMLINES][LINESIZE+1];
  85. char text[2*LINESIZE];
  86. int  line_tab[NUMLINES];
  87. int  actline = 0;
  88.  
  89. #define LPR_PORT    515
  90.  
  91. /* -------------------------------------------------------------------- */
  92. /*    Extern definierte globale Variablen.                              */
  93. /* -------------------------------------------------------------------- */
  94. /* Mittels dieser Variablen kann    */
  95. extern int _app;  /* das Programm feststellen, ob es  */
  96. /* als Accessory oder normale App-  */
  97. /* likation gestartet wurde.        */
  98. extern int flag;
  99. extern int fhandle;
  100. extern char path[];
  101. extern long oldgem;
  102. extern long grpgem;
  103.  
  104. /* -------------------------------------------------------------------- */
  105. /*    Globale Variablen.                                                */
  106. /* -------------------------------------------------------------------- */
  107. int get_response(void);
  108. void output1(int o_len, char *o_str);
  109. void output(char *o_str);
  110. void printfile(FILE *fin);
  111. int connect(char * host, int port);
  112. void redraw_window( int all );
  113. int handle_message(int *pipe);
  114. void multi( void );
  115. void event_loop( void );
  116. void spool(void);
  117.  
  118. int  whandle;          /* Handle für geöffnetes Fenster.   */
  119. char title[] = "Printer Dämon";  /* Titelzeile des Fensters.         */
  120. int  gl_wchar;        /* Größe und Breite eines Buchsta-  */
  121. int gl_hchar;        /* ben (wichtig falls mit unter-    */
  122. int gl_wbox;        /* schiedlichen Bildschirmauflö-    */
  123. int gl_hbox;          /* sungen gearbeitet wird) bzw.     */
  124.                     /* einer Box.                       */
  125. int  phys_handle;    /* Handles für GEM und VDI.         */
  126. int handle;
  127. int  max_x;            /* Maximale Größe der Arbeitsfläche */
  128. int max_y;
  129. int  appl_id;        /* Identifikationsnummer des Prog.  */
  130. int menu_id;              /* Id.-nummer im Menü 'Desk'.       */
  131.  
  132. int line_height = 8;
  133. int cell_width = 8;
  134.  
  135. int dum;
  136. int x,y,w,h;
  137. int attrib[10];
  138.  
  139. int scroll_log(int actline)
  140. {  /* rotate log lines */
  141.   int i;
  142.   int line;
  143.  
  144.   if(actline < NUMLINES-1) return(actline+1);
  145.   line = line_tab[0];
  146.   for(i=0; i<NUMLINES-1; i++)
  147.   {
  148.     line_tab[i] = line_tab[i+1];
  149.   }
  150.   line_tab[NUMLINES-1] = line;
  151.   return(NUMLINES-1);
  152. }
  153.  
  154. int log(char *str)
  155. {
  156.   int i;
  157.   char *s;
  158.   int len,inline;
  159.  
  160.   if(!str) return(0);
  161.   len = (int)strlen(str);
  162.   if(str[len-1] == '\r')
  163.   {
  164.     str[len-1] = 0;
  165.     inline = 1;
  166.     len--;
  167.   }
  168.   else inline = 0;
  169.   
  170.   log_text[line_tab[actline]][0] = 0;
  171.   if(!len)
  172.     actline = scroll_log(actline);
  173.   s = log_text[line_tab[actline]];
  174.   while(len)
  175.   {
  176.     for(i=0; i <= LINESIZE; i++)
  177.     {
  178.       *s++ = str[i];
  179.       if(!str[i]) break;
  180.       len--;
  181.     }
  182.     *s=0;
  183.     if(!inline) actline = scroll_log(actline);
  184.     if(!inline) s = log_text[line_tab[actline]];
  185.   }
  186.   *s = 0;
  187.   redraw_window(1);
  188.   return(1);
  189. }
  190.  
  191. void open_window( void )
  192. {
  193.   if(whandle <= 0)
  194.   {
  195.     whandle = wind_create(NAME|CLOSER|MOVER, 0, 0, max_x + 1, max_y + 1 );
  196.     if( whandle <= 0 )
  197.       return;
  198.  
  199.     wind_set(whandle, WF_NAME, title);
  200.     vst_font(handle, 1);  /* auswählen       */
  201.     vst_height(handle, ZH, &dum,&dum,&cell_width,&line_height);  /* set small font   */
  202.     vqt_attributes( handle, attrib );
  203.     vst_alignment(handle, 0, 4, &dum, &dum);
  204.     wind_calc(WC_BORDER, NAME|CLOSER|MOVER , 80, 80, cell_width*LINESIZE, line_height*NUMLINES, &x, &y, &w, &h);
  205.     wind_open(whandle, x,y,w,h+15);
  206.   }
  207.   else
  208.     wind_set( whandle, WF_TOP );
  209. }
  210.  
  211. /* -------------------------------------------------------------------- */
  212. /*    min()                                                             */
  213. /*                                                                      */
  214. /*    Minimum zweier Zahlen berechnen.                                  */
  215. /* -------------------------------------------------------------------- */
  216.  
  217. int min( int a, int b)
  218. {
  219.   if( a > b )
  220.     return( b );
  221.   else
  222.     return( a );
  223. }
  224.  
  225. /* -------------------------------------------------------------------- */
  226. /*    max()                                                             */
  227. /*                                                                      */
  228. /*    Maximum zweier Zahlen bestimmen.                                  */
  229. /* -------------------------------------------------------------------- */
  230.  
  231. int max( int a, int b)
  232. {
  233.   if( a < b )
  234.     return( b );
  235.   else
  236.     return( a );
  237. }
  238.  
  239. /* -------------------------------------------------------------------- */
  240. /*    rc_intersect()                                                    */
  241. /*                                                                      */
  242. /*    Schnittfläche zweier Rechtecke berechnen.                         */
  243. /* -------------------------------------------------------------------- */
  244.  
  245. int rc_intersect(GRECT *r1, GRECT *r2)
  246. {
  247.   int xl, yu, xr, yd;  /* left, upper, right, down */
  248.  
  249.   xl      = max( r1->g_x, r2->g_x );
  250.   yu      = max( r1->g_y, r2->g_y );
  251.   xr      = min( r1->g_x + r1->g_w, r2->g_x + r2->g_w );
  252.   yd      = min( r1->g_y + r1->g_h, r2->g_y + r2->g_h );
  253.  
  254.   r2->g_x = xl;
  255.   r2->g_y = yu;
  256.   r2->g_w = xr - xl;
  257.   r2->g_h = yd - yu;
  258.  
  259.   return( r2->g_w > 0 && r2->g_h > 0 );
  260. }
  261.  
  262. /* -------------------------------------------------------------------- */
  263. /*    mouse_on()                                                        */
  264. /*                                                                      */
  265. /*    Mauszeiger anschalten.                                            */
  266. /* -------------------------------------------------------------------- */
  267.  
  268. void mouse_on(void)
  269.  
  270. {
  271.   graf_mouse( M_ON, (void *)0 );
  272. }
  273.  
  274. /* -------------------------------------------------------------------- */
  275. /*    mouse_off()                                                       */
  276. /*                                                                      */
  277. /*    Mauszeiger ausschalten.                                           */
  278. /* -------------------------------------------------------------------- */
  279.  
  280. void mouse_off(void)
  281. {
  282.   graf_mouse( M_OFF, (void *)0 );
  283. }
  284. /* -------------------------------------------------------------------- */
  285. /*    redraw_window()                                                   */
  286. /*                                                                      */
  287. /*    Fensterinhalt neu zeichnen, nachdem er zuvor aus irgendeinem      */
  288. /*    Grunde zerstört wurde, oder weil das Fenster neu geöffnet wurde.  */
  289. /* -------------------------------------------------------------------- */
  290.  
  291. void redraw_window( int all )
  292. {
  293.   GRECT   box,
  294.   work;
  295.   int     clip[4];
  296.   int     line,dum;
  297.   int         height;
  298.  
  299.   if( whandle <= 0 )  /* Wenn kein Fenster auf ist,    */
  300.     return;  /* braucht auch nicht gezeichnet */
  301.   /* zu werden.                    */
  302.  
  303.   if(all)
  304.   {
  305.  
  306.     mouse_off();
  307.  
  308.     vsf_color( handle, 0 );  /* set white fill   */
  309.     vswr_mode( handle, 1 );  /* set replace mode */
  310.     vst_height( handle, 6, &dum,&dum,&dum,&height);  /* set small font   */
  311.  
  312.     wind_get( whandle, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w,
  313.     &work.g_h );
  314.     wind_get( whandle, WF_FIRSTXYWH, &box.g_x, &box.g_y, &box.g_w,
  315.     &box.g_h );
  316.     work.g_w = min( work.g_w, max_x - work.g_x + 1 );
  317.     work.g_h = min( work.g_h, max_y - work.g_y + 1 );
  318.  
  319.     while ( box.g_w > 0 && box.g_h > 0 )
  320.     {
  321.       if( rc_intersect( &work, &box ) )
  322.       {
  323.         clip[0] = box.g_x;
  324.         clip[1] = box.g_y;
  325.         clip[2] = box.g_x + box.g_w - 1;
  326.         clip[3] = box.g_y + box.g_h - 1;
  327.  
  328.         vs_clip( handle, 1, clip );
  329.         if( all )
  330.           vr_recfl( handle, clip );
  331.         /* fill rectangle */
  332.         for(line=0;line < NUMLINES; line++)
  333.         {
  334.           v_gtext( handle, work.g_x, work.g_y + 15 + (line*height),log_text[line_tab[line]]);
  335.         }
  336.  
  337.       }
  338.       wind_get( whandle, WF_NEXTXYWH, &box.g_x, &box.g_y, &box.g_w,
  339.       &box.g_h );
  340.     }
  341.     mouse_on();
  342.   }
  343. }
  344.  
  345. /* -------------------------------------------------------------------- */
  346. /*    handle_message()                                                  */
  347. /*                                                                      */
  348. /*    Auswertung der Ereignisse des Multi-Events bezüglich des Message- */
  349. /*    buffers.                                                          */
  350. /* -------------------------------------------------------------------- */
  351.  
  352. int handle_message(int *pipe)
  353. {
  354.   switch ( pipe[0] )
  355.   {
  356.   case WM_REDRAW:
  357.     redraw_window(1);
  358.     break;
  359.  
  360.   case WM_TOPPED:
  361.     wind_set( whandle, WF_TOP );
  362.     break;
  363.  
  364.   case WM_CLOSED:
  365.     if( pipe[3] == whandle )
  366.     {
  367.       wind_close( whandle );
  368.       wind_delete( whandle );
  369.       whandle = 0;
  370.     }
  371.     if( _app )
  372.       return(1);
  373.     break;
  374.  
  375.   case WM_MOVED:
  376.   case WM_SIZED:
  377.     if( pipe[3] == whandle )
  378.       wind_set( whandle, WF_CURRXYWH,  pipe[4], pipe[5],
  379.       pipe[6], pipe[7] );
  380.     break;
  381.  
  382.   case AC_OPEN:
  383.     if( pipe[4] == menu_id )
  384.       open_window();
  385.     break;
  386.  
  387.   case AC_CLOSE:
  388.     if( pipe[3] == menu_id )
  389.       whandle = 0;
  390.     break;
  391.   }
  392.   return(0);
  393. }
  394.  
  395. /* -------------------------------------------------------------------- */
  396. /*    event_loop()                                                      */
  397. /*                                                                      */
  398. /*    Die Multi-Event-Schleife.                                         */
  399. /* -------------------------------------------------------------------- */
  400.  
  401. void event_loop( void )
  402. {
  403.   quit = 0;
  404.   do
  405.   {
  406.     event = evnt_multi( MU_MESAG | MU_TIMER,
  407.     2, 0x1, 1,
  408.     0, 0, 0, 0, 0,
  409.     0, 0, 0, 0, 0,
  410.     pipe,
  411.     100, 0,
  412.     &x, &y, &state, &kstate, &key, &clicks );
  413.  
  414.     wind_update(BEG_UPDATE);
  415.  
  416.     if( event & MU_MESAG)
  417.       quit = handle_message( pipe );
  418.     wind_update(END_UPDATE);
  419.  
  420.     if( event & MU_TIMER)
  421.     {
  422.       if(flag)
  423.       {
  424.         open_window();
  425.         sprintf(text,"attempt to print file %s ...",&path);
  426.         log(text);
  427.         file_to_print = path;
  428.         spool();
  429.         if(tcp_ok)
  430.         {
  431.          sprintf(text,"File %s printed.",&path);
  432.          log(text);
  433.         }
  434.         /*wind_close( whandle );
  435.         wind_delete( whandle );
  436.         whandle = 0;*/
  437.         flag = 0;
  438.       }
  439.     }
  440.  
  441.  
  442.   }
  443.   while (!quit);
  444. }
  445.  
  446. void multi( void )
  447. {
  448.   do
  449.   {
  450.     event = evnt_multi( MU_MESAG | MU_TIMER,
  451.     2, 0x1, 1,
  452.     0, 0, 0, 0, 0,
  453.     0, 0, 0, 0, 0,
  454.     pipe,
  455.     100, 0,
  456.     &x, &y, &state, &kstate, &key, &clicks );
  457.  
  458.     wind_update(BEG_UPDATE);
  459.  
  460.     if( event & MU_MESAG) quit = handle_message( pipe );
  461.     wind_update(END_UPDATE);
  462.     if(quit)
  463.     {
  464.       tcp_close(tcp);
  465.       break;
  466.     }
  467.     if( event & MU_TIMER) break;
  468.   }
  469.   while (1);
  470. }
  471.  
  472. /* -------------------------------------------------------------------- */
  473. /*    main()                                                            */
  474. /*                                                                      */
  475. /*    Kernstück des Programms.                                          */
  476. /* -------------------------------------------------------------------- */
  477.  
  478. int main( void )
  479. {
  480.   int i;
  481.   int work_in[11];
  482.   int work_out[57];
  483.  
  484.   /* ----------------------------------------------------------------- */
  485.   /* Initialization                                                    */
  486.   /* ----------------------------------------------------------------- */
  487.  
  488.   appl_id = appl_init();
  489.   if( appl_id != -1 )
  490.   {
  491.     for (i = 0; i < 10; i++)
  492.       work_in[i]  = 1;
  493.     work_in[10] = 2;
  494.     phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox,
  495.     &gl_hbox );
  496.     whandle = 0;
  497.     handle = phys_handle;
  498.     v_opnvwk( work_in, &handle, work_out );
  499.     for(i=0; i< NUMLINES; i++)        /* init log table */
  500.     {
  501.         line_tab[i] = i;
  502.         log_text[i][0] = 0;
  503.     }
  504.     actline = 0;
  505.     if( handle != 0 )
  506.     {
  507.       max_x = work_out[0];
  508.       max_y = work_out[1];
  509.       oldgem = (long)Setexc(33, (void (*)())&grpgem);
  510.  
  511.       term = (char *)getenv("PRINTER");
  512.       if(!term)   strcpy(printer,"lp");
  513.       else   strcpy(printer,term);
  514.  
  515.       term = (char *)getenv("USER");
  516.       if(!term)   strcpy(user,"ST-spoold");
  517.       else   strcpy(user,term);
  518.  
  519.       term = (char *)getenv("HOSTNAME");
  520.       if(!term)   strcpy(hostname,"ST");
  521.       else   strcpy(hostname,term);
  522.       strtok(hostname,".");  /* cut off domainname */
  523.  
  524.       term = (char *)getenv("PRINTHOST");
  525.       if(!term)  sprintf(printhost,"fortec");
  526.       else strcpy(printhost,term);
  527.  
  528.       if( !_app )
  529.       {
  530.         menu_id = menu_register( appl_id, "  Spoold" );
  531.         /*open_window();*/
  532.       }
  533.       else
  534.       {
  535.         graf_mouse( 0, (void*)0 );
  536.         open_window();
  537.       }
  538.       /* ----------------------------------------------------------------- */
  539.       /* Event Loop                                                        */
  540.       /* ----------------------------------------------------------------- */
  541.  
  542.       sprintf(text,"No file active...");
  543.       log(text);
  544.       event_loop();
  545.  
  546.       /* ----------------------------------------------------------------- */
  547.       /* Deinitialization                                                  */
  548.       /* ----------------------------------------------------------------- */
  549.  
  550.       oldgem = (long)Setexc(33, (void (*)())oldgem);
  551.       v_clsvwk( handle );
  552.     }
  553.     appl_exit();
  554.   }
  555.   return(0);
  556. }
  557.  
  558. /* -------------------------------------------------------------------- */
  559. /*    End of SPOOLD.C                                                     */
  560. /* -------------------------------------------------------------------- */
  561.  
  562. void spool(void)
  563. {
  564.   tcp_ok = FALSE;
  565.   sprintf(text,"Trying 4.3 bsd print server %s, device %s ...",printhost,printer);
  566.   log(text);
  567.  
  568.   Supexec(set_pd);
  569.   fin = fopen(file_to_print, "rb");
  570.   Supexec(restore_pd);
  571.  
  572.   if(fin == NULL) 
  573.   {
  574.     sprintf(text,"<Error: can't open file '%s'>", file_to_print);
  575.     log(text);
  576.     tcp_ok = FALSE;
  577.   }
  578.   else
  579.   {
  580.     timev = clock();
  581.     number = (((timev >> 24) & 0xff) + ((timev >> 16) & 0xff))*15 +
  582.         ((timev >> 10) );
  583.     Supexec(set_pd);
  584.     fseek(fin, 0L,SEEK_END);
  585.     filelength = ftell(fin);
  586.     fseek(fin, 0L, 0);
  587.     Supexec(restore_pd);
  588.     lensent = 0;    
  589.     if((tcp = connect(printhost,LPR_PORT)) > 0)
  590.     {
  591.       tcp_ok = TRUE;
  592.       printfile(fin); 
  593.       tcp_close(tcp);
  594.     }
  595.     else
  596.     {
  597.       sprintf(text,"<Error: no response from %s>",printhost);
  598.       log(text);
  599.       tcp_ok = FALSE;
  600.     }
  601.     Supexec(set_pd);
  602.     fclose(fin);
  603.     Fdelete(file_to_print);
  604.     Supexec(restore_pd);
  605.   }
  606. }
  607. /* open a connection and return tcp handle, 0 if error */
  608.  
  609. int connect(char * host, int port)
  610. {
  611.   int tcp_id, state;
  612.  
  613.   term = (char *)getenv("TCPWND");
  614.   if(term) tcp_buff = atoi(term);
  615.  
  616.   desti.Port = port;
  617.  
  618.   if(GetIPAddr(host,desti.IPAddr))
  619.   {
  620.     unsigned int tmp1,tmp2,tmp3,tmp4;
  621.  
  622.     if(sscanf(host,"%d.%d.%d.%d",&tmp1,&tmp2,&tmp3,&tmp4) != 4)
  623.     {
  624.       sprintf(text,"<Error: unknown host.>");
  625.       log(text);
  626.       return 0;
  627.     }
  628.     desti.IPAddr[0] = tmp1;
  629.     desti.IPAddr[1] = tmp2;
  630.     desti.IPAddr[2] = tmp3;
  631.     desti.IPAddr[3] = tmp4;
  632.   }
  633.  
  634.   tcp_id = (unsigned)tcp_open(721+(int)(Random() % 10),&desti,AKTIV,60,(long)tcp_buff);
  635.  
  636.   if(tcp_id == 0)
  637.   {
  638.     sprintf(text,"<Error: could not open connection.>");
  639.     log(text);
  640.     return 0;
  641.   }
  642.  
  643.   do
  644.   {
  645.     state = (int)tcp_stat(tcp_id,&tstat);
  646.     if((state > ESTABLISHED) || (state <= CLOSED)) break;
  647.     multi();
  648.   }
  649.   while(state < ESTABLISHED);
  650.  
  651.   if(state != ESTABLISHED)
  652.   {
  653.     sprintf(text,"<Error: connection refused.>");
  654.     log(text);
  655.     return 0;
  656.   }
  657.   return(tcp_id);
  658. }
  659.  
  660. void printfile(FILE *fin)
  661. {
  662.   /* connection is open, start the lprd protocol */
  663.   sprintf(o_str, "\2%s\n",printer);
  664.   output(o_str);
  665.   if(get_response() > 1)
  666.   {
  667.     sprintf(text,"%s",data);
  668.     log(text);
  669.   }
  670.   if(response == '\1') 
  671.   {
  672.     sprintf(text,"<Error: printer server didn't accept printer>");
  673.     log(text);
  674.     tcp_ok = FALSE;
  675.     return;
  676.   }
  677.   else if(response != '\0') 
  678.   {
  679.     tcp_ok = FALSE;
  680.     return;
  681.   }
  682.   sprintf(filename, "fA%03ld%s",(number++) % 999,hostname);
  683.   /* get file length */
  684.   sprintf(o_str, "\3%ld d%s\n", filelength, filename);
  685.   output(o_str);
  686.   if(get_response() > 1)
  687.   {
  688.     sprintf(text,"%s",data);
  689.     log(text);
  690.   }
  691.   if(response == '\1') 
  692.   {
  693.     sprintf(text,"<Error: connection messed up, try again>");
  694.     log(text);
  695.     tcp_ok = FALSE;
  696.     return;
  697.   }
  698.   else if(response == '\2') 
  699.   {
  700.     sprintf(text,"<Error: server out of storage space>");
  701.     log(text);
  702.     tcp_ok = FALSE;
  703.     return;
  704.   }
  705.   else if(response != '\0') 
  706.   {
  707.     tcp_ok = FALSE;
  708.     return;
  709.   }
  710.  
  711.   do
  712.   {
  713.     Supexec(set_pd);
  714.     lendata = fread(file_buffer, 1, mmin((long)FILE_BUF_SIZE,filelength),fin);
  715.     Supexec(restore_pd);
  716. #ifdef DEBUG
  717.     printf("read %ld bytes\n",lendata);
  718. #endif
  719.     if(lendata <= 0)
  720.     {
  721.       file_buffer[0] = 0;
  722.       output1(1,file_buffer);
  723.     }
  724.     if(lendata < 0)
  725.     {
  726.       return;
  727.     }
  728.     lensent += lendata;
  729.     sprintf(text,"%ld %%\r",(lensent * 100) / filelength);
  730.     log(text);
  731.     output1((int)lendata,file_buffer);
  732.     multi();
  733.   }
  734.   while(lendata > 0);      
  735.  
  736.   if(get_response() > 1)
  737.   {
  738.     sprintf(text,"%s",data);
  739.     log(text);
  740.   }
  741.   if(response != '\0') 
  742.   {
  743.     sprintf(text,"<Error: data file not properly transferred, aborting>");
  744.     log(text);
  745.     tcp_ok = FALSE;
  746.     return;
  747.   }
  748. #ifdef DEBUG
  749.   printf("file closed\n");
  750. #endif
  751.   /* build the control file */
  752.   sprintf(file_buffer, "H%s\n",hostname);
  753.   sprintf(file_buffer+strlen(file_buffer), "P%s\n", user);
  754.   sprintf(file_buffer+strlen(file_buffer), "J%s\n", file_to_print);
  755.   sprintf(file_buffer+strlen(file_buffer), "C%s\n", hostname);
  756.   sprintf(file_buffer+strlen(file_buffer), "L%s\n", user);
  757.   sprintf(file_buffer+strlen(file_buffer), "fd%s\n", filename);
  758.   sprintf(file_buffer+strlen(file_buffer), "Ud%s\n", filename);
  759.   sprintf(file_buffer+strlen(file_buffer), "N%s\n", file_to_print);
  760.   sprintf(o_str, "\2%ld c%s\n", strlen(file_buffer), filename);
  761.   output(o_str);
  762.   if(get_response() > 1)
  763.   {
  764.     sprintf(text,"%s",data);
  765.     log(text);
  766.   }
  767.   if(response == '\1') 
  768.   {
  769.     sprintf(text,"<Error: connection messed up, try again>");
  770.     log(text);
  771.     tcp_ok = FALSE;
  772.     return;
  773.   }
  774.   else if(response == '\2') 
  775.   {
  776.     sprintf(text,"<Error: server out of storage space>");
  777.     log(text);
  778.     tcp_ok = FALSE;
  779.     return;
  780.   }
  781.   else if(response != '\0') 
  782.   {
  783.     tcp_ok = FALSE;
  784.     return;
  785.   }
  786.   output1((int)strlen(file_buffer)+1,file_buffer);
  787.   if(get_response() > 1)
  788.   {
  789.     sprintf(text,"%s",data);
  790.     log(text);
  791.   }
  792.   if(response != '\0') 
  793.   {
  794.     sprintf(text,"<Error: control file not properly transferred, aborting>");
  795.     log(text);
  796.     tcp_ok = FALSE;
  797.     return;
  798.   }
  799. }
  800.  
  801. void output(char *o_str)
  802. {
  803.   int o_len;
  804.  
  805.   o_len = (int)strlen(o_str);
  806.   output1(o_len, o_str);
  807. }
  808.  
  809. void output1(int o_len, char *o_str)
  810. {
  811.   int i,j;
  812.  
  813.   for(i=0; i < o_len;)
  814.   {
  815.     j = (int)tcp_write(tcp,o_str+i,o_len-i,PUSH,NO_URGENT);
  816.     if(j>=0) i += j;
  817.     else
  818.     {
  819.       sprintf(text,"connection broken");
  820.       log(text);
  821.       tcp_ok = FALSE;
  822.       break;
  823.     }
  824.     multi();
  825. #ifdef DEBUG
  826.     printf("send %d bytes\n",j);
  827. #endif
  828.   }
  829. }
  830.  
  831. int get_response(void)
  832. {
  833.   int length;
  834.  
  835.   do
  836.   {
  837.     multi();
  838.     length = (int)tcp_read(tcp,data,INBUFSIZE);
  839.   } 
  840.   while(!length);
  841.   if(length < 0) return length;
  842.   response = data[0];
  843.   return length;
  844. }
  845.  
  846. long set_pd(void)
  847. {
  848.   oldpd = SYSBASE->_run;
  849.   SYSBASE->_run = &_BasPag;
  850.   return 0;
  851. }
  852.  
  853. long restore_pd(void)
  854. {
  855.   SYSBASE->_run = oldpd;
  856.   return 0;
  857. }
  858.